<?php

// +----------------------------------------------------------------------
// | 任务返修订单服务层
// +----------------------------------------------------------------------
// | 主要服务于合同
// +----------------------------------------------------------------------
// | 错误编码头 251xxx
// +----------------------------------------------------------------------
namespace common\service;

use common\exception\LogicException;
use common\model\EntityModel;
use common\model\MediaModel;
use common\model\NoteEntityRelationModel;
use common\model\NoteModel;
use common\model\OrderModel;
use common\model\OrderTaskListModel;
use common\model\ProjectModel;
use common\model\RepairOrderAffectedTaskModel;
use common\model\RepairTaskWorkOrderRelationModel;
use common\model\ReviewFeedbackModel;
use common\model\ReviewRequestModel;
use common\model\ReviewRequestNodeModel;
use common\model\TaskModel;
use common\model\TaskRepairOrderModel;
use common\model\TaskWorkOrderModel;
use common\model\TaskWorkOrderUserModel;
use common\model\UserModel;
use common\model\VersionCheckListModel;
use common\model\VersionModel;
use malkusch\lock\mutex\PHPRedisMutex;
use support\bootstrap\Redis;
use support\ErrorCode;
use support\SingletonTrait;
use think\Exception;
use think\Hook;
use think\module\Module;
use Throwable;
use Webman\Stomp\Client;

/**
 * Class TaskRepairOrderService
 * @package common\service
 */
class TaskRepairOrderService
{
    // 单例工具
    use SingletonTrait;

    /** @var TaskRepairOrderModel $taskRepairOrderModel */
    private $taskRepairOrderModel;

    public function __construct()
    {
        $this->taskRepairOrderModel = model(TaskRepairOrderModel::class);
    }

    /**
     * 创建返修单
     * @param $data
     * @return array
     * @throws Exception
     * @throws Throwable
     */
    public function create($data): array
    {
        $task = model(TaskModel::class)->find($data['task_id']);
        if (empty($task)) {
            throw new LogicException("can`t found task", ErrorCode::TASK_NOT_FOUND);
        }
        $data['entity_id'] = $task['entity_id'];
        $data['step_category_id'] = $task['step_category_id'];
        $data['step_id'] = $task['step_id'];
        $data['project_id'] = $task['project_id'];
        $data['step_id'] = $task['step_id'];
        $reviewRequestService = ReviewRequestService::getInstance();
        $assignUserId = $task['assignee_producer'];
        if ($assignUserId == 0) {
            $parentTask = model(TaskModel::class)->where(['entity_id' => $task['entity_id'], 'step_category_id' => $data['step_category_id'], 'step_type' => 'step_category'])->find();
            $assignUserId = $parentTask['assignee'];
            // 如果分配制片为空 那么使用分类任务分配人
        }

        $assignUserLocal = model(UserModel::class)->where(['id' => $assignUserId])->field("id,union_id")->find();
        $assignUser = teamones_request('teamones-im', 'user/get_other_user_info', [
            'user_id' => $assignUserLocal['union_id'],
        ])['data'];
        if (empty($assignUser['role_info'])) {
            throw new LogicException("task assignee producer role_code not found", ErrorCode::USER_INFO_NOT_FOUND);
        }
        $roleInfo = array_shift($assignUser['role_info']);
        $this->taskRepairOrderModel->startTrans();
        try {

            $taskRepairOrder = $this->taskRepairOrderModel->addItem($data);
            $reviewData = [
                'reviewers' => [
                    [
                        'role_code' => $roleInfo['code'],
                        'user_id' => $assignUserLocal['id'],
                        'skip' => false,
                    ],
                ],
                'data' => [
                    'review_workflow_id' => 0,
                    'name' => "返修单审核 {$taskRepairOrder['id']}",
                    'param' => $taskRepairOrder,
                    'link_id' => $taskRepairOrder['id'],
                    'module_id' => Module::$moduleDictData['module_index_by_code']['task_repair_order']['id'],
                ],
            ];
            $reviewRequest = $reviewRequestService->create($reviewData);
            $this->taskRepairOrderModel->commit();
            // 通知任务分配人审核
            //            try {
            //                $this->notifyFirstReviewer($taskRepairOrder, $reviewRequest['nodes'][0]);
            //            } catch (\Throwable $e) {
            //                trace(format_exception_info($e), 'ERR');
            //            }
            return ['review_request' => $reviewRequest, 'task_repair_order' => $taskRepairOrder];
        } catch (Throwable $e) {
            $this->taskRepairOrderModel->rollback();
            throw $e;
        }
    }

    /**
     *  处理返修订单审核状态变化
     * @param int $repairOrderId 返修单id
     * @param bool $isPass 是否通过
     * @param int $taskRepairStepCategoryId 返修环节id (工序分类id)
     * @throws \Exception
     */
    public function handleRepairOrderReviewed(int $repairOrderId, bool $isPass, int $taskRepairStepCategoryId)
    {
//        $repairOrder = $this->taskRepairOrderModel->find($repairOrderId);
        if ($isPass) {
            $modifyStatus = 'active';
        } else {
            $modifyStatus = 'deny';
        }
        $updateData = [
            'id' => $repairOrderId,
            'status' => $modifyStatus,
        ];
        if ($taskRepairStepCategoryId > 0) {
            $updateData['repair_step_category_id'] = $taskRepairStepCategoryId;
        }
        $this->taskRepairOrderModel->modifyItem($updateData);

        // 通知返修环节组长
        //        if ($isPass) {
        //            try {
        //                $this->notifyRepairStepCategoryHeadman($repairOrder);
        //            } catch (\Throwable $e) {
        //                trace(format_exception_info($e), 'ERR');
        //                // 通知逻辑不throw
        //            }
        //        }
    }

    /**
     * 开始返修
     * @param $param
     * @param int $userId
     * @param bool $fromDemandOrder 是否从需求单调用
     * @return array
     * @throws \Exception
     */
    public function start($param, int $userId, bool $fromDemandOrder = false)
    {
        $res = [
            'entity_change_status_task_step_category' => [],
        ];
        // 判定是否组内还是组外 ,组外则未跨环节
        $taskList = model(TaskModel::class)->where(["id" => ["IN", [$param["task_id"], $param["need_repair_task_id"]]]])->select();
        $taskList = array_column($taskList, null, "id");
        $task = $taskList[$param["task_id"]];
        $needRepairTask = $taskList[$param["need_repair_task_id"]];
        $dontRepairStepCategoryIdList = $param['dont_repair_step_category'] ?? [];
        if ($param["task_id"] != $param["need_repair_task_id"]) {
            $repairType = $task["step_category_id"] != $needRepairTask["step_category_id"] ? "cross_group" : "group_in";
        } else {
            $repairType = "group_in";
        }
        $statusService = StatusService::getInstance();

        //未开始的不能进行返修
        $notStartedStatus = $statusService->getNotStartedStatus();
        $notStartedStatus = array_column($notStartedStatus, 'id');
        $taskJson = json_decode($needRepairTask['json'], true);
        $needRepairTaskStepWorkflowId = $taskJson['step_workflow_id'] ?? 0;
        if (!empty($taskJson['task_status']) && in_array($taskJson['task_status'], $notStartedStatus)) {
            throw new LogicException('The task cannot be repaired', ErrorCode::THE_TASK_CANNOT_BE_REPAIRED);
        }

        $relationNote = null;
        // 如果提前填入相关 的返修意见 ,将不再生成返修意见
        if (!empty($param["note_id"])) {
            if (is_array($param["note_id"])) {
                $relationNote = model(NoteModel::class)->find($param["note_id"][0]);
            } else {
                $relationNote = model(NoteModel::class)->find($param["note_id"]);
            }
            $relationNoteJson = json_decode($relationNote['json'], true);
            if (!empty($relationNote["review_feedback_id"])) {
                $reviewFeedback = model(ReviewFeedbackModel::class)->field("id,status,permissions,demand_type")->find($relationNote["review_feedback_id"]);
                if ($reviewFeedback['demand_type'] === ReviewFeedbackModel::DEMAND_TYPE_REVIEW_FEEDBACK) {
                    ReviewFeedbackService::getInstance()->reviewFeedbackPermissionsDeal($reviewFeedback["permissions"], "send_repair");
                }
            }

            // 判定是否 能被返修 (当前状态是否是待发起返修)
            if ($relationNote["demand_status"] !== NoteModel::DEMAND_STATUS_PENDING) {
                throw new LogicException("demand status not pending", ErrorCode::DEMAND_STATUS_NOT_PENDING);
            }

            $param["text"] = $relationNote["text"] ?? "";
            $param["reason_type"] = $relationNoteJson["reason_type"] ?? "";
        }

        //没有发起者工单,默认获取到当前任务的工单 (排除掉返修)
        if (empty($param["send_repair_work_order"])) {
            $untreatedWorkOrderStatus = TaskWorkOrderService::getInstance()->getOptionsMergeItemStatus("untreated");
            $sendRepairWorkOrderFilter = ["task_id" => $param['need_repair_task_id'], "status" => ["IN", $untreatedWorkOrderStatus]];
        } else {
            $sendRepairWorkOrderFilter = ["id" => ["IN", $param["send_repair_work_order"]]];
        }

        $sendRepairWorkOrderList = model(TaskWorkOrderModel::class)->where($sendRepairWorkOrderFilter)->field("id,name,chat_global_id")->select();
        $sendRepairWorkOrderIds = [];
        if (!empty($sendRepairWorkOrderList)) {
            $sendRepairWorkOrderIds = array_column($sendRepairWorkOrderList, "id");
        }

        $repairOrderAdd = [
            'submitter_id' => $userId,
            'task_id' => $needRepairTask['id'],
            'step_category_id' => $needRepairTask['step_category_id'],
            'step_id' => $needRepairTask['step_id'],
            'entity_id' => $needRepairTask['entity_id'],
            'tenant_id' => $needRepairTask['tenant_id'],
            'project_id' => $needRepairTask['project_id'],
            'effect_task_number' => 0,
            'repair_step_category_id' => $needRepairTask['step_category_id'],
            'status' => 'default',
            'created_by' => $userId,
            'repair_task_id' => $needRepairTask['id'],
            'repair_reason' => $param["text"] ?? "",
            'report_type' => $param["reason_type"] ?? '',
            'task_work_order_id' => $param["task_work_order_id"] ?? 0,
        ];

        if ($repairType === 'cross_group') {
            // 组外查询返修单 验证返修单状态
            $repairOrderAdd['task_id'] = $task['id'];
            $repairOrderAdd['step_category_id'] = $task['step_category_id'];
            $repairOrderAdd['step_id'] = $task['step_id'];
            $repairOrderAdd['entity_id'] = $task['entity_id'];
            $repairOrderAdd['tenant_id'] = $task['tenant_id'];
            $repairOrderAdd['project_id'] = $task['project_id'];
        }

        // 关联订单在 进行中/待发起结算 才可进行返修
        $relatedOrder = OrderService::getInstance()->getOrderByStepTaskId($needRepairTask['id']);
        $allowRepairOrderStatusList = ['inprogress', 'wait_for_add_settlement'];
        if (!empty($relatedOrder)) {
            if (!in_array($relatedOrder['status'], $allowRepairOrderStatusList)) {
                throw new LogicException('order status can`t repair task', ErrorCode::THE_TASK_CANNOT_BE_REPAIRED_BY_ORDER_STATUS);
            }
            $needRepairTask = OrderService::getInstance()->getSourceTaskByTaskId($needRepairTask['id']);
        }

        // 所有的下游实体
        $entityIdList = EntityUpstreamService::getInstance()->getDownstreamEntityList($needRepairTask['entity_id'], false);
        $entityIdList[] = $needRepairTask['entity_id'];
        $taskListFilter = [
            'task.entity_id' => ['IN', implode(',', $entityIdList)],
            'task.step_type' => 'step',
        ];
        if (!empty($dontRepairStepCategoryIdList)) {
            $taskListFilter['task.step_category_id'] = ['NOT IN', implode(',', $dontRepairStepCategoryIdList)];
        }
        $taskList = model(TaskModel::class)
            ->join('entity on entity.id = task.entity_id')
            ->where($taskListFilter)
            ->field("task.id,task.tenant_id,task.entity_id,task.step_id,task.step_category_id,task.executor,json_unquote(json_extract(task.json,'$.task_status')) as task_status,entity.module_id,entity.json entity_json,entity.initial_episode_code,entity.showings_number")
            ->select();
        $stepService = StepService::getInstance();
        $downstreamSteps = $stepService->getAllStepDownstreamMap($needRepairTask['project_id'], $needRepairTaskStepWorkflowId, false);
        $downstreamTaskList = [];
        $taskList = array_group_by($taskList, 'step_id');
        $this->findAllDownstreamTask($taskList, $downstreamSteps, $needRepairTask, $downstreamTaskList);
        $taskDefaultStatus = $statusService->getTaskDefaultStatus(); // 未开始
        $taskReadyStatus = $statusService->getTaskDefaultReadyStatus(); // 就绪
        $taskWaitAssembleStatus = $statusService->getTaskWaitAssembleStatus(); // 待组装
        $taskClosedStatus = $statusService->getTaskDefaultClosedStatus(); // 已取消

        $statusFilter = [null, '', $taskDefaultStatus['id'], $taskReadyStatus['id'], $taskWaitAssembleStatus['id']];

        // 需要重置状态为未开始的任务 重新等待上游完成然后进待组装
        // 获取待组装的任务
        $resetToNotStartedTaskList = [];
        // 获取开始的下游任务
        $startedDownstreamTaskList = [];
        foreach ($downstreamTaskList as $downstreamTaskId => $downstreamTaskItem) {
            if (intval($downstreamTaskItem['task_status']) === $taskWaitAssembleStatus['id']) {
                $resetToNotStartedTaskList[] = $downstreamTaskItem;
            }
            if (!in_array($downstreamTaskItem['task_status'], $statusFilter) && $taskClosedStatus['id'] != $downstreamTaskItem['task_status']) {
                $startedDownstreamTaskList[$downstreamTaskId] = $downstreamTaskItem;
            }
        }
        //加入本身的返修任务id
        if (!isset($startedDownstreamTaskList[$needRepairTask["id"]])) {
            $startedDownstreamTaskList[$needRepairTask["id"]] = $needRepairTask;
        }
        $changeToStartStatusTaskIds = [];
        $changeToStartStatusTaskList = array_values($startedDownstreamTaskList);

        $needAddNoteEntityRelationData = !empty($relationNote) && !$fromDemandOrder;// 是否需要添加反馈关联关系
        $needAddNoteRelationData = [];
        // 兼容反馈数据格式
        if (!empty($param['note_id']) && !is_array($param['note_id'])) {
            $param['note_id'] = [$param['note_id']];
        }
        // 组装返修的实体和环节信息
        foreach ($changeToStartStatusTaskList as $changeToStartStatusTask) {
            $changeToStartStatusTaskIds[] = $changeToStartStatusTask['id'];
            // 跳过当前实体和环节
            if ($changeToStartStatusTask['id'] == $needRepairTask['id']) {
                continue;
            }
            $entityModuleCode = module_by_id($changeToStartStatusTask['module_id'])['code'];
            $entityJson = json_decode($changeToStartStatusTask['entity_json'], true);
            if (in_array($entityModuleCode, ['storyboard', 'design'])) {
                $entityId = $changeToStartStatusTask['entity_id'];
            } else {
                if (in_array($entityModuleCode, ['asset', 'level'])) {
                    $upstreamEntityField = $entityModuleCode . '_design';
                } else {
                    $upstreamEntityField = $entityModuleCode . '_storyboard';
                }
                $entityId = $entityJson[$upstreamEntityField] ?? 0;
            }

            if ($entityId == 0) {
                continue;
            }
            if ($needAddNoteEntityRelationData) {
                foreach ($param['note_id'] as $noteId) {
                    $needAddNoteRelationData[] = [
                        'note_id' => $noteId,
                        'relation_type' => NoteEntityRelationModel::RELATION_TYPE_STEP,
                        'relate_module_code' => $relationNote['module_code'],
                        'project_id' => $relationNote['project_id'],
                        'episode_code' => $changeToStartStatusTask['initial_episode_code'],
                        'entity_id' => $entityId,
                        'task_id' => $changeToStartStatusTask['id'],
                        'created' => time(),
                        'created_by' => $userId,
                        'step_category_id' => $changeToStartStatusTask['step_category_id'],
                        'step_id' => $changeToStartStatusTask['step_id'],
                        'scene' => $changeToStartStatusTask['showings_number'],
                        'from_upstream_step_category_id' => $needRepairTask['step_category_id'] === $changeToStartStatusTask['step_category_id'] ? 0 : $needRepairTask['step_category_id'],
                        'review_feedback_id' => $relationNote['review_feedback_id'],
                        'task_is_start' => 'yes',
                    ];
                }
            }
        }
        //需要返修的任务id
        $needRepairTaskIds = $changeToStartStatusTaskIds;
        // 所有版本
        $versions = model(VersionModel::class)->where(['link_id' => ['IN', $changeToStartStatusTaskIds], 'module_id' => Module::$moduleDictData['module_index_by_code']['task']['id']])->field('id,number,link_id')->select();

        //获取当前最大版本id
        $taskMaxVersionMap = [];
        foreach ($versions as $versionsItem) {
            if (empty($taskMaxVersionMap[$versionsItem["link_id"]])) {
                $taskMaxVersionMap[$versionsItem["link_id"]] = ['id' => $versionsItem["id"], 'number' => $versionsItem["number"]];
            } else {
                if ($taskMaxVersionMap[$versionsItem["link_id"]]["number"] < $versionsItem["number"]) {
                    $taskMaxVersionMap[$versionsItem["link_id"]] = ['id' => $versionsItem["id"], 'number' => $versionsItem["number"]];
                }
            }
        }

        // 任务对应的订单任务列表
        $repairGetOrderTaskLisData = $this->repairGetOrderTaskLisData($changeToStartStatusTaskIds);

        $orderIdList = $repairGetOrderTaskLisData["order_id_list"]; //获取订单id
        $partyATaskIdList = $repairGetOrderTaskLisData["party_a_task_id_list"]; //获取甲方任务
        $partyBTaskIdList = $repairGetOrderTaskLisData["party_b_task_id_list"]; //获取甲方任务
        if (!empty($partyATaskIdList)) {
            $needRepairTaskIds = array_merge($needRepairTaskIds, $partyATaskIdList);
            $partyATaskList = model(TaskModel::class)->where(['id' => ['IN', implode(',', $partyATaskIdList)]])->select();
            $changeToStartStatusTaskList = array_merge($changeToStartStatusTaskList, $partyATaskList);
        }
        if (!empty($partyBTaskIdList)) {
            $needRepairTaskIds = array_merge($needRepairTaskIds, $partyBTaskIdList);
            $partyBTaskList = model(TaskModel::class)->where(['id' => ['IN', implode(',', $partyBTaskIdList)]])->select();
            $changeToStartStatusTaskList = array_merge($changeToStartStatusTaskList, $partyBTaskList);
        }
        $changeToStartStatusTaskList = array_values(array_column($changeToStartStatusTaskList, null, 'id'));

        //获取还未审核完的审核列表
        $reviewRequestList = [];
        //获取当前审核节点
        $currentReviewNodeIds = [];
        //获取下一个审核节点
        $nextReviewNode = [];
        if (!empty($versions)) {
            $repairGetReviewRequestData = $this->repairGetReviewRequestData($versions);
            $reviewRequestList = $repairGetReviewRequestData["review_request_list"];
            $currentReviewNodeIds = $repairGetReviewRequestData["current_review_node_ids"];
            $nextReviewNode = $repairGetReviewRequestData["next_review_node"];
        }
        //当前节点工单失效
        $repairTag = OptionsService::getInstance()->getOptionsConfigItemData('def_task_work_order_tag', 'repair_tag');
        if (empty($repairTag)) {
            throw new LogicException('def task work order tag not exist', ErrorCode::DEF_TASK_WORK_ORDER_TAG_NOT_EXIST);
        }
        $dismantleTaskIds = DismantleTaskService::getInstance()->getDismantleTaskIds($changeToStartStatusTaskIds); // 查询主任务下面的子任务
        if (!empty($dismantleTaskIds)) {
            $dismantleTaskIds = array_column($dismantleTaskIds, 'id');
        }

        // 避免重复创建
        $repairOrderAddId = $repairOrderAdd["repair_task_id"];
        $repairOrder = null;
        $mutex = new PHPRedisMutex([Redis::connection()->client()], "task_repair_order_create-$repairOrderAddId", 5);
        $mutex->synchronized(function () use (
            $repairOrderAdd, $param, $changeToStartStatusTaskList, $changeToStartStatusTaskIds, $taskMaxVersionMap, $sendRepairWorkOrderIds,
            $needRepairTaskIds, $orderIdList, $resetToNotStartedTaskList, $versions, $reviewRequestList,
            $currentReviewNodeIds, $repairTag, $nextReviewNode, &$res, &$repairOrder, $userId,
            $dismantleTaskIds, $relationNote, $needAddNoteRelationData, $fromDemandOrder
        ) {
            $statusService = StatusService::getInstance();

            $taskDefaultStartStatus = $statusService->getTaskDefaultStartStatus(); // 进行中
            $taskDefaultStatus = $statusService->getTaskDefaultStatus(); // 未开始
            $defaultRemakeStatus = $statusService->getTaskDefaultRemakeStatus();
            if (empty($defaultRemakeStatus)) {
                throw new LogicException('did not config default task start status', ErrorCode::MISSING_TASK_DEFAULT_START_STATUS_CONFIG);
            }
            $taskModel = model(TaskModel::class);
            $mediaModel = model(MediaModel::class);
            $commonService = CommonService::instance('task_repair_order');
            $taskModel->startTrans();
            try {
                //添加返修单
                if (!empty($repairOrderAdd)) {

                    if (!empty($param['task_repair_order_media'])) {
                        $mediaIds = [];
                        foreach ($param['task_repair_order_media'] as $mediaItem) {
                            MediaService::getInstance()->generateMediaData($mediaItem);
                            $mediaData = $mediaModel->addItem($mediaItem);
                            if (!$mediaData) {
                                throw new LogicException($mediaModel->getError(), ErrorCode::MEDIA_ADD_FAILURE);
                            } else {
                                $mediaIds[] = $mediaData['id'];
                            }
                        }
                        if (!empty($mediaIds)) {
                            $repairOrderAdd['task_repair_order_media'] = join(',', $mediaIds);
                        }
                    }

                    $repairOrderAdd['effect_task_number'] = count($changeToStartStatusTaskList);
                    $res['task_repair_order'] = $repairOrder = $commonService->create($repairOrderAdd);
                    //返修时添加被影响的任务
                    $this->repairAddAffectedTask($repairOrder, $changeToStartStatusTaskList, $taskMaxVersionMap);

                    //添加工单关联
                    $sendRepairWorkOrderData = [];
                    if (!empty($sendRepairWorkOrderIds)) {
                        foreach ($sendRepairWorkOrderIds as $sendRepairWorkOrderId) {
                            $sendRepairWorkOrderData[] = [
                                "task_work_order_id" => $sendRepairWorkOrderId,
                                "task_repair_order_id" => $repairOrder["id"],
                            ];
                        }
                        if (!empty($sendRepairWorkOrderData)) {
                            model(RepairTaskWorkOrderRelationModel::class)->addAll($sendRepairWorkOrderData);
                        }
                    }
                }

                $taskRepairChangedList = [
                    'from_demand_order' => $fromDemandOrder,
                    'changed' => $changeToStartStatusTaskList,
                    'need_repair_task_id' => $param["need_repair_task_id"],
                    'operator' => $userId,
                    'need_repair_task_id_list' => $needRepairTaskIds,
                    'relation_note' => $relationNote,
                    'time' => time(),
                ];
                // 发起返修动作 来自需求单的不通知
                $hookData = [
                    'type' => 'task_repair',
                    'data' => [
                        'params' => $taskRepairChangedList,
                    ]
                ];
                Hook::listen('task_repair', $hookData);

                // 更新 任务状态为 默认返修状态,处理状态 (包含甲方任务,开始过的下游任务)
                if (!empty($needRepairTaskIds)) {
                    $needRepairTaskIds = join(",", $needRepairTaskIds);
                    $this->taskRepairOrderModel->execute("UPDATE task SET json = json_set(IFNULL(json,'{}'),'$.task_status',{$defaultRemakeStatus['id']}) WHERE id IN ($needRepairTaskIds)");
                }

                // 子任务更新为进行中
                if (!empty($dismantleTaskIds)) {
                    $dismantleTaskIds = join(",", $dismantleTaskIds);
                    $this->taskRepairOrderModel->execute("UPDATE task SET json = json_set(IFNULL(json,'{}'),'$.task_status',{$taskDefaultStartStatus['id']}) WHERE id IN ($dismantleTaskIds)");
                }

                // 当前返修任务的关联订单修改为进行中
                if (!empty($orderIdList)) {
                    model(OrderModel::class)->where(['id' => ['IN', $orderIdList]])->save(['status' => 'inprogress']);
                }

                // 更新待组装的下游任务为未开始
                if (!empty($resetToNotStartedTaskList)) {
                    $resetToNotStartedTaskIdStr = implode(',', array_column($resetToNotStartedTaskList, 'id'));
                    $this->taskRepairOrderModel->execute("UPDATE task SET json = JSON_SET(IFNULL(json,'{}'),'$.task_status',{$taskDefaultStatus['id']}) WHERE id IN ($resetToNotStartedTaskIdStr)");
                }

                // 所有的版本修改为未通过
                if (!empty($versions)) {

                    $versionCheckListListId = model(VersionCheckListModel::class)->where(['version_id' => ['IN', implode(',', array_column($versions, 'id'))]])->select();
                    // 版本审核节点修改为 未通过 ,版本暂时不修改为不通过
                    if (!empty($versionCheckListListId)) {
                        $versionCheckListListId = array_column($versionCheckListListId, "id");
                        model(VersionCheckListModel::class)->where(["id" => ["IN", $versionCheckListListId]])->save(['is_pass' => 'no']);
                    }
                    // 修改审核记录 , 进行中的审核修改为拒绝
                    if (!empty($reviewRequestList)) {
                        $reviewRequestListIds = array_column($reviewRequestList, 'id');
                        model(ReviewRequestModel::class)->save(['is_pass' => 'no', 'is_reviewed' => 'yes', 'reviewed' => time()], ['where' => ['id' => ['IN', implode(',', $reviewRequestListIds)]]]);
                    }
                    //修复该当前审核节点以及审核节点的工单
                    if (!empty($currentReviewNodeIds)) {
                        model(ReviewRequestNodeModel::class)->where(['id' => ['IN', $currentReviewNodeIds]])->save(['is_pass' => 'no', 'is_reviewed' => 'yes', 'is_second_confirm' => 'yes', 'is_active' => 'no', 'reviewed' => time()]);
                        $taskWorkOrderList = model(TaskWorkOrderModel::class)->where(['review_request_node_id' => ["IN", $currentReviewNodeIds], 'type' => 'review_feedback'])->field('id')->select();
                        if (!empty($taskWorkOrderList)) {
                            $taskWorkOrderListIds = array_column($taskWorkOrderList, 'id');
                            $taskWorkOrderListIds = join(',', $taskWorkOrderListIds);
                            $statusExpired = TaskWorkOrderModel::STATUS_EXPIRED;
                            model(TaskWorkOrderModel::class)
                                ->execute("UPDATE task_work_order SET json = json_set(IFNULL(json,'{}'),'$.task_work_order_tag',{$repairTag}),status = {$statusExpired} WHERE id IN ($taskWorkOrderListIds) and type ='review_feedback' ");
                        }
                    }
                    //中止下一批节点
                    if (!empty($nextReviewNode)) {
                        model(ReviewRequestNodeModel::class)->where(['id' => ['IN', $nextReviewNode]])->save(['is_pass' => 'no', 'is_reviewed' => 'yes', 'is_terminate' => 'yes', 'is_active' => 'no', 'is_second_confirm' => 'yes']);
                    }
                }
                if (count($needAddNoteRelationData) > 0) {
                    model(NoteEntityRelationModel::class)->addAll($needAddNoteRelationData);
                }
                $taskModel->commit();
            } catch (Throwable $e) {
                $taskModel->rollback();
                throw $e;
            }
        });

        if (!empty($repairOrder)) {
            try {
                //返修完成,发送工单消息
                if (!empty($sendRepairWorkOrderIds)) {
                    $this->initiateRepairWorkOrderMessage($sendRepairWorkOrderList, $sendRepairWorkOrderIds);
                }

                try {
                    // 开始返修给对应实体群发送消息
                    $entity = model(EntityModel::class)->where(['id' => $needRepairTask['entity_id']])->find();
                    $chatService = ChatService::getInstance();
                    $chat = $chatService->createEntityChat($entity);
                    if ($chat) {
                        $message['type'] = 'repair_entity_task_message';
                        $message = $chatService->getEntityTaskMessageTemplate($message, request()->getUserId(), $entity, $needRepairTask);
                        $chatService->pushEntityTaskMessage($message, $chat);
                    }
                } catch (Throwable $e) {
                    trace(format_exception_info($e), 'ERR');
                }

                //发起返修之后,关闭没有群聊的工单
                if (!empty($repairOrderAdd['task_work_order_id'])) {
                    $repairTaskWorkOrder = model(TaskWorkOrderModel::class)->field("id,chat_global_id,status")->find($repairOrderAdd['task_work_order_id']);
                    if (!empty($repairTaskWorkOrder) && empty($repairTaskWorkOrder['chat_global_id']) && in_array($repairTaskWorkOrder['status'], TaskWorkOrderModel::STATUS_NOT_CLOSED_GROUP)) {
                        model(TaskWorkOrderModel::class)->modifyItem(['id' => $repairTaskWorkOrder['id'], 'status' => TaskWorkOrderModel::STATUS_PROCESSED]);
                    }
                }

                // 操作成功后通知受影响任务执行人 任务进行返修中

                if (!empty($repairOrderAdd) && empty($param["note_id"])) {
                    $this->appendNoteToChangeStatusTaskList($needRepairTask, $changeToStartStatusTaskList);
                }

                //如果传入的note为审核反馈下的返修意见 需要将其返修状态更改为进行中状态,审核反馈需要由未开始变成进行中
                if (!empty($relationNote) && in_array($relationNote['demand_type'], [NoteModel::DEMAND_TYPE_REVIEW_FEEDBACK, NoteModel::DEMAND_TYPE_REPAIR_FEEDBACK])) {
                    model(NoteModel::class)->modifyItem(["id" => $relationNote["id"], 'task_repair_order_id' => $repairOrder['id'], 'demand_status' => NoteModel::DEMAND_STATUS_PROCESSING]);
                    if (!empty($reviewFeedback) && $reviewFeedback['status'] === ReviewFeedbackModel::STATUS_NOT_STARTED) {
                        model(ReviewFeedbackModel::class)->modifyItem(['id' => $relationNote["review_feedback_id"], 'status' => ReviewFeedbackModel::STATUS_IN_PROGRESS]);
                    }
                }
            } catch (Throwable $e) {
                trace(format_exception_info($e), 'ERR');
            }
        }

        return $res;

    }

    /**
     * 查询任务关联的返修单
     * @param $taskId
     * @param $userId
     * @param $param
     * @return array|null
     * @throws \Exception
     */
    public function GetByTaskId($taskId, $userId, $param)
    {
        $task = model(TaskModel::class)->find($taskId);
        if (empty($task)) {
            throw new LogicException('task not found', ErrorCode::TASK_NOT_FOUND);
        }
        // 关联的已通过的返修单
        // 提交人能看到 默认状态和审核通过状态下的返修单
        // 返修环节组长能看到激活中的返修单

        // 返修单查询
        /**
         * 1. 提交人为当前用户 并且返修单状态在 default默认状态 (未审核)下
         * 2. 返修单状态为active 返修环节分类id为当前任务分类id 并且当前用户为组长
         */
        $param['filter'] = [
            ['task_repair_order.task_id' => $taskId, 'task_repair_order.status' => "default", 'task_repair_order.submitter_id' => $userId],
            ['task_repair_order.entity_id' => $task['entity_id'], 'task_repair_order.repair_step_category_id' => $task['step_category_id'], 'task_repair_order.status' => 'active'],
            '_logic' => 'OR',
        ];
        $res = model(TaskRepairOrderModel::class)
            ->findData($param);

        if (empty($res)) {
            return null;
        }
        if (is_many_dimension_array($res)) {
            $res = array_merge($res, $res['task_repair_order']);
        }

        if ($res['repair_step_category_id'] == $task['step_category_id'] && $res['status'] == "active") {
            // 当前任务是返修环节 并且返修单已经激活
            // 当前任务分配人是否是当前用户

            if ($task['assignee'] != $userId) {
                $res = null;
            } else {
                $res['from_other'] = true;
            }
        } else {
            // 当前任务为发起返修任务
            // 当前用户为提交人

            // 查询返修单审核人
            $res['reviewer'] = model(ReviewRequestNodeModel::class)
                ->join('review_request ON review_request.id = review_request_node.review_request_id')
                ->join('user ON user.id = review_request_node.plan_reviewer')
                ->where([
                    'review_request.link_id' => $res['id'],
                    'review_request.module_id' => Module::$moduleDictData['module_index_by_code']['task_repair_order']['id'],
                    'review_request_node.is_reviewed' => 'no',
                ])
                ->field('user.*')
                ->find();
            $res['from_other'] = false;
        }

        return $res;
    }

    /**
     * 返修环节 查询
     * @param $taskId
     * @return array|false|mixed|string
     */
    public function getRepairStepCategory($taskId)
    {
        $task = model(TaskModel::class)->find($taskId);
        $stepCategoryId = $task['step_category_id'];
        $currentStepCategoryTask = model(TaskModel::class)
            ->where([
                'entity_id' => $task['entity_id'],
                'step_type' => 'step_category',
                'step_category_id' => $stepCategoryId,
            ])->find();

        return model(TaskModel::class)
            ->where([
                'entity_id' => $task['entity_id'],
                'step_type' => 'step_category',
                'id' => [
                    'LT', $currentStepCategoryTask['id'],
                ],
            ])->select();
    }

    /**
     * 筛选出所有下游任务
     * @param $taskList
     * @param array $downStreamMap
     * @param $currentTask
     * @param array $downstreamTaskList
     */
    private function findAllDownstreamTask($taskList, array $downStreamMap, $currentTask, array &$downstreamTaskList)
    {
        if (!empty($downStreamMap[$currentTask['step_id']])) {
            foreach ($downStreamMap[$currentTask['step_id']] as $downStepId) {
                if (empty($taskList[$downStepId])) {
                    continue;
                }
                foreach ($taskList[$downStepId] as $task) {
                    if (array_key_exists($task['id'], $downstreamTaskList)) {
                        continue;
                    }
                    $downstreamTaskList[$task['id']] = $task;
                    $this->findAllDownstreamTask($taskList, $downStreamMap, $task, $downstreamTaskList);
                }
            }
        }
    }

    /**
     * 返修时添加被影响的任务
     * @throws \Exception
     */
    public function repairAddAffectedTask($repairOrder, $changeToStartStatusTaskList, $taskMaxVersionMap)
    {
        $repairOrderAffectedTaskList = [];
        foreach ($changeToStartStatusTaskList as $changeToStartStatusTaskItem) {
            $taskId = $changeToStartStatusTaskItem['id'];
            $repairOrderAffectedTaskList[] = [
                "task_repair_order_id" => $repairOrder["id"],
                "task_id" => $taskId,
                "version_id" => $taskMaxVersionMap[$taskId]["id"] ?? 0,
                "created" => time(),
                "entity_id" => $changeToStartStatusTaskItem['entity_id'],
                'step_category_id' => $changeToStartStatusTaskItem['step_category_id'],
                'step_id' => $changeToStartStatusTaskItem['step_id'],
            ];
        }
        //添加被影响的任务
        model(RepairOrderAffectedTaskModel::class)->addAll($repairOrderAffectedTaskList);
    }

    /**
     * 获取返修时审核的数据
     * @param $versions
     * @return array
     */
    public function repairGetReviewRequestData($versions)
    {
        //获取还未审核完的审核列表
        $reviewRequestList = [];
        //获取当前审核节点
        $currentReviewNodeIds = [];
        //获取下一个审核节点
        $nextReviewNode = [];
        if (!empty($versions)) {
            // 进行中的审核修改为拒绝
            $reviewRequestList = model(ReviewRequestModel::class)->where(['link_id' => ['IN', implode(',', array_column($versions, 'id'))], 'module_id' => Module::$moduleDictData['module_index_by_code']['version']['id'], 'is_reviewed' => 'no'])->field('id')->select();
            //审核列表 修改为 以完成 | 审核列表子项 修改为

            $reviewRequestNodeList = model(ReviewRequestNodeModel::class)->where(['review_request_id' => ['IN', implode(',', array_column($reviewRequestList, 'id'))]])->select();
            $reviewRequestNodeListGrouped = array_group_by($reviewRequestNodeList, 'review_request_id');
            //获取当前节点,以及当前节点之后的
            foreach ($reviewRequestNodeListGrouped as $reviewRequestNodeArray) {
                $currentReviewNode = [];
                $currentReviewPass = true;
                foreach ($reviewRequestNodeArray as $reviewRequestNodeItem) {
                    if ($currentReviewPass) {
                        if ($reviewRequestNodeItem['is_reviewed'] === 'yes') {
                            $currentReviewNode = $reviewRequestNodeItem['id'];
                        } else {
                            $currentReviewPass = false;
                            $nextReviewNode[] = $reviewRequestNodeItem['id'];
                        }
                    } else { //记录当前节点之后的
                        $nextReviewNode[] = $reviewRequestNodeItem['id'];
                    }
                }
                if (!empty($currentReviewNode)) {
                    $currentReviewNodeIds[] = $currentReviewNode;
                }

            }
        }

        return [
            "review_request_list" => $reviewRequestList,
            "current_review_node_ids" => $currentReviewNodeIds,
            "next_review_node" => $nextReviewNode,
        ];
    }

    /**
     * 获取返修时订单任务的数据
     * @param $taskIdStr
     * @return array
     */
    public function repairGetOrderTaskLisData($taskIdStr)
    {
        //获取订单id
        $orderIdList = [];
        //获取甲方任务
        $partyATaskIdList = [];
        //获取乙方任务
        $partyBTaskIdList = [];
        // 任务对应的订单任务列表
        $orderTaskList = model(OrderTaskListModel::class)->where(['task_id' => ['IN', $taskIdStr]])
            ->field('id,order_id,deal_status,real_task_id,task_id')
            ->select();

        foreach ($orderTaskList as $orderTaskItem) {
            $orderIdList[$orderTaskItem['order_id']] = $orderTaskItem['order_id'];
            $partyBTaskIdList[] = $orderTaskItem['real_task_id'];
        }

        $orderTaskList = model(OrderTaskListModel::class)->where(['real_task_id' => ['IN', $taskIdStr]])
            ->field('id,order_id,deal_status,real_task_id,task_id')
            ->select();

        foreach ($orderTaskList as $orderTaskItem) {
            $orderIdList[$orderTaskItem['order_id']] = $orderTaskItem['order_id'];
            $partyATaskIdList[] = $orderTaskItem['task_id'];
        }

        return [
            "order_id_list" => $orderIdList,
            "party_a_task_id_list" => $partyATaskIdList,
            "party_b_task_id_list" => $partyBTaskIdList,
        ];
    }

    /**
     * 发起返修推送工单消息
     * @param $sendRepairWorkOrderList
     * @param $taskWorkOrderIds
     */
    public function initiateRepairWorkOrderMessage($sendRepairWorkOrderList, $taskWorkOrderIds)
    {
        $taskWorkOrderUserList = model(TaskWorkOrderUserModel::class)
            ->join("user on user.id = task_work_order_user.user_id")
            ->where(["task_work_order_user.work_order_id" => ["IN", $taskWorkOrderIds]])
            ->field("task_work_order_user.work_order_id,user.union_id")->select();
        $taskWorkOrderUserGroup = array_group_by($taskWorkOrderUserList, "work_order_id");

        foreach ($sendRepairWorkOrderList as $taskWorkOrderItem) {
            if (empty($taskWorkOrderItem['chat_global_id'])) {
                continue;
            }
            if (isset($taskWorkOrderUserGroup[$taskWorkOrderItem['id']])) {
                $imUserIds = array_unique(array_column($taskWorkOrderUserGroup[$taskWorkOrderItem['id']], 'union_id'));
                $requestData = [
                    "data" => [
                        'receives' => $imUserIds,
                        'content_type' => "initiate_repair",
                        'global_id' => $taskWorkOrderItem['chat_global_id'],
                        'content_extra_data' => ['work_order_id' => $taskWorkOrderItem['id'], 'work_order_name' => $taskWorkOrderItem['name']],
                    ],
                ];
                teamones_request('teamones-im', 'message/push_work_order_chat_message', $requestData);
            }
        }
    }

    /**
     * 处理返修完成影响的任务
     * @param $taskIds
     * @return array|void
     */
    public function dealFinishRepairOrderAffectedTask($taskIds)
    {
        if (empty($taskIds)) {
            return [];
        }

        //找到未返修完的受影响任务
        $repairOrderAffectedTaskModel = model(RepairOrderAffectedTaskModel::class);
        $repairOrderAffectedTaskList = $repairOrderAffectedTaskModel->forceMasterDB()->where(["task_id" => ["IN", $taskIds], "repair_status" => "no"])->field("id,task_id,task_repair_order_id")->select();

        if (empty($repairOrderAffectedTaskList)) {
            return;
        }

        $repairTaskWorkOrderIds = [];
        $repairTaskWorkOrderAffectedTaskMap = [];
        foreach ($repairOrderAffectedTaskList as $repairOrderAffectedTaskItem) {

            $repairTaskWorkOrderIds[$repairOrderAffectedTaskItem["task_repair_order_id"]] = $repairOrderAffectedTaskItem["task_repair_order_id"];
            //一个返修工单里只会存在唯一的任务id
            $repairTaskWorkOrderAffectedTaskMap[$repairOrderAffectedTaskItem["task_repair_order_id"]] = $repairOrderAffectedTaskItem["task_id"];
        }

        // 返修完成最后一个版本查询
        $versionParam = [
            'filter' => [
                'module_id' => module_by_code('task')['id'],
                'link_id' => ['IN', $taskIds],
                'is_deprecate' => 'no',
            ],
            'fields' => 'max(id) as id',
            'group' => 'link_id',
        ];
        $manyLatestVersion = VersionService::getInstance()->getManyLatestVersion($versionParam);
        $manyLatestVersion = array_column($manyLatestVersion, 'id', 'link_id');

        $repairTaskWorkOrderIds = array_values($repairTaskWorkOrderIds);

        // 返修完成需要修改审核反馈的返修意见状态
        // 通过 为完成的返修单找到 返修意见
        // 目前的关系(一对一) task_repair_order -> note -> note_entity_relation
        $noteList = model(TaskRepairOrderModel::class)->forceMasterDB()
            ->join("note on note.task_repair_order_id = task_repair_order.id")
            ->where([
                "task_repair_order.repair_task_id" => ["IN", $taskIds],
//                "task_repair_order.status" => "default",
                "note.demand_type" => ['IN', [NoteModel::DEMAND_TYPE_REPAIR_FEEDBACK, NoteModel::DEMAND_TYPE_REVIEW_FEEDBACK]],
                "note.demand_status" => NoteModel::DEMAND_STATUS_PROCESSING,
            ])->field("note.id,note.review_feedback_id")->select();

        $noteIds = [];
        $reviewFeedbackIds = [];
        foreach ($noteList as $noteItem) {
            $noteIds[] = $noteItem['id'];
            if ($noteItem['review_feedback_id'] > 0 && !in_array($noteItem['review_feedback_id'], $reviewFeedbackIds)) {
                $reviewFeedbackIds[] = $noteItem['review_feedback_id'];
            }
        }

        $repairOrderAffectedTaskModel->startTrans();
        try {
            foreach ($repairOrderAffectedTaskList as $repairOrderAffectedTaskItem) {
                $repairDoneVersionId = $manyLatestVersion[$repairOrderAffectedTaskItem['task_id']] ?? 0;
                $repairOrderAffectedTaskModel->modifyItem(['id' => $repairOrderAffectedTaskItem['id'], 'repair_status' => 'yes', 'repair_done_version_id' => $repairDoneVersionId]);
            }

            //找出已经全部返修完的返修单,将其完成
            $taskWorkOrderIds = $repairOrderAffectedTaskModel->forceMasterDB()
                ->where(["task_repair_order_id" => ["IN", $repairTaskWorkOrderIds], "repair_status" => "no"])
                ->field("task_repair_order_id")
                ->group("task_repair_order_id")
                ->select();
            $taskWorkOrderIds = array_column($taskWorkOrderIds, "task_repair_order_id");
            $repairFinishTaskWorkOrderIds = array_diff($repairTaskWorkOrderIds, $taskWorkOrderIds);
            if (!empty($repairFinishTaskWorkOrderIds)) {
                model(TaskRepairOrderModel::class)->where(["id" => ["IN", $repairFinishTaskWorkOrderIds]])->save(["status" => "done"]);
            }

            //将返修意见的状态更新为已完成
            if (!empty($noteIds)) {
                $noteResult = model(NoteModel::class)->where(["id" => ["IN", $noteIds]])->save(["demand_status" => NoteModel::DEMAND_STATUS_FINAL]);
                if ($noteResult === false) {
                    throw new LogicException(model(NoteModel::class)->getError(), model(NoteModel::class)->getErrorCode());
                }
                // 审核反馈状态处理
                if (!empty($reviewFeedbackIds)) {
                    ReviewFeedbackService::getInstance()->dealReviewFeedbackFinalStatus($reviewFeedbackIds);
                }
            }

            $repairOrderAffectedTaskModel->commit();

            //返修任务成功工单消息推送
            try {
                Client::send("repair_task_success_work_order_message_notify", build_queue_data_with_xu(["data" => $repairTaskWorkOrderAffectedTaskMap]));
            } catch (Throwable $e) {
                trace(format_exception_info($e), 'ERR');
            }
        } catch (Throwable $e) {
            $repairOrderAffectedTaskModel->rollback();
            trace(format_exception_info($e), 'ERR');
        }
    }

    /** 查询实体返修任务列表
     * @param int $currentTaskId
     * @param int $wantRepairEntityId
     * @return array|false|mixed|string
     */
    public function getEntityRepairStepList(int $currentTaskId, int $wantRepairEntityId)
    {
        $currentTask = model(TaskModel::class)->find($currentTaskId);
        $project = model(ProjectModel::class)->find($currentTask['project_id']);
        if (empty($currentTask)) {
            throw new LogicException("task not found", ErrorCode::TASK_NOT_FOUND);
        }

        $currentTaskJson = json_decode($currentTask['json'], true);
        $stepWorkflowId = $currentTaskJson['step_workflow_id'] ?? 0;

        if ($currentTask['entity_id'] == $wantRepairEntityId) {
            $res = TaskUpstreamService::getInstance()->getAllUpstreamEntityTask($currentTaskId);
            $taskIdList = array_column($res, 'id');
            if (!in_array($currentTaskId, $taskIdList)) {
                $res[] = [
                    'id' => $currentTaskId,
                    'step_category_id' => $currentTask['step_category_id'],
                    'name' => $currentTask['name'],
                    'task_status' => $currentTaskJson['task_status'] ?? 0,
                ];
            }
        } else {
            $upstreamProcess = StepService::getInstance()->getUpstreamProcess($project["project_template_id"] ?? 0, $currentTask['project_id'] ?? 0, $stepWorkflowId, $currentTask["step_id"] ?? 0, true, true);
            $upstreamFilter = [
                "entity_id" => $wantRepairEntityId,
                "step_type" => "step",
                'step_id' => ['IN', $upstreamProcess['step_list']],
            ];
            $res = model(TaskModel::class)
                ->where($upstreamFilter)
                ->field("id,step_category_id,name,json->>'$.task_status' as task_status")
                ->select();
        }

        return $res;
    }

    /**
     * 追加反馈到修改状态的任务上
     * @param $needRepairTask
     * @param array $changeToStartStatusTaskList
     * @return void
     * @throws Throwable
     */
    private function appendNoteToChangeStatusTaskList($needRepairTask, array $changeToStartStatusTaskList)
    {
        $entityIds = array_unique(array_column($changeToStartStatusTaskList, "entity_id"));
        $entityList = model(EntityModel::class)->where(["id" => ["IN", $entityIds]])->field("id,initial_episode_code")->select();
        $entityList = array_column($entityList, null, "id");

        if (in_array($needRepairTask["entity_module_id"], [module_by_code("asset")["id"], module_by_code("level")["id"], module_by_code("design")["id"]])) {
            $noteEntityModuleCode = "asset";
        } else {
            $noteEntityModuleCode = "shot";
        }
        $noteRelationList = [];
        foreach ($changeToStartStatusTaskList as $changeToStartStatusTaskItem) {
            $noteRelationList[] = [
                "relation_type" => "step",
                "project_id" => $needRepairTask["project_id"],
                "relate_module_code" => $noteEntityModuleCode,
                "episode_code" => $entityList[$changeToStartStatusTaskItem["entity_id"]]["initial_episode_code"] ?? "",
                "entity_id" => $changeToStartStatusTaskItem["entity_id"],
                "task_id" => $changeToStartStatusTaskItem["id"],
            ];
        }

        $noteData = [
            'note' => [
                'type' => 'text',
                "demand_type" => "repair_feedback",
                "module_code" => $noteEntityModuleCode,
                'tenant_id' => $needRepairTask['tenant_id'],
                'text' => $repairOrderAdd["repair_reason"] ?? "",
                'reason_type' => $repairOrderAdd["report_type"] ?? '',
                "project_id" => $needRepairTask["project_id"],
            ],
        ];

        if (!empty($param['task_repair_order_media'])) {
            $noteData["note_media"] = $param['task_repair_order_media'];
        }

        if (!empty($noteRelationList)) {
            $noteData["note_entity_relation"] = $noteRelationList;
        }
        // 创建反馈
        NoteService::getInstance()->createNote($noteData);
    }
}
